- 三个概念,理(bei)解(song)一下:
- 第一行分别是PID,PPID,PGID,SID,COMMAND,依次分别是进程ID,该进程父进程ID,进程组ID,会话ID,命令。
- 第三行则是ps命令的进程,其进程ID为15816,他是由于bash进程fork出来的,所以他的父进程ID为15793,然后是他所属的组ID为15816,所属的会话ID依然是15793。
- 简单总结一下:
- 将上述文件保存为daemon.php,然后php daemon.php执行,使用 ps -aux | grep testte ,如果没有什么大问题你应该就可以看到这个进程在后台跑了。
- 啦啦啦,明白为啥篇头那一坨枯燥的知识是为了什么吧?
- 将文件保存为daemon.php,然后php daemon.php执行文件,嗯,是不是有怪怪的现象,大概类似于下图:
- 其次是将当前工作目录修改更改为根目录。不然可能就会出现下面这样一个问题,就是如果父进程是的工作目录是一个挂载的目录,那么子进程会继承父进程的工作目录,当子进程已经daemon化后就会出现一个悲剧:那就是虽然原来挂载的目录已经不用了,但是却无法用umount卸载,非常悲剧。
其实前面是谈过一次daemon进程的,但是并涉及过多原理,但是并不影响使用。今天打算说说关于daemon进程更多的二三事,本质上说,如果你仅仅是简单实现利用一下daemon进程,这个不看也是可以的。
杠真,*NIX真是波大精深,越是深入看越是发现它的diao。原理往往都是枯燥的,大家都不爱看,但这并不影响我坚持写自己对这些东西的理解。
三个概念,理(bei)解(song)一下:
- 进程组。一坨相关的进程可以组成一个进程组,每个进程组都会有一个组ID(正整数),每个进程组都会有一个组长进程,组长进程的ID等于进程组ID。组长进程可以创建新的进程组以及该进程组中的其他进程。一个进程组的是有生命周期的,即便是组长进程挂了,只有组里还有其他的活口,那就就算该进程组依然存活,只有到组里最后一个活口也挂了,那真的就是彻底没了。
- 会话。一坨相关的进程组组成了一个会话。在*NIX下,是通过setsid()创建一个新的会话。但是值得注意的是,组长进程不能创建会话,简单理解就是在组长进程中,执行setsid函数会报错,这点很重要。所以一般都是组长进程执行fork,然后主进程退出,因为子进程的进程ID是新分配的,而子进程的进程组ID是继承父进程的,所以子进程就注定不可能是组长进程,从而可以确保子进程中一定可以执行setsid函数。在执行setsid函数时候,一般会发生下面三个比较重要的事情:
- 该进程会创建一个新的进程组,该进程为进程组组长(或者你可以认为这是一种提升)
- 该进程会创建一个会话组并成为该会话的会话首进程(会话首进程就是创建该会话的进程)
- 该进程会失去控制终端。如果该进程本来就没有控制终端,则罢了(liao)。如果有,那么该进程也将脱离该控制终端,与之失去联系。
- 控制终端。每个会话可能会拥有一个控制终端(看着比较玄学,你可以暂时理解为就一个那种黑乎乎的命令行窗口),建立与控制终端连接的会话首进程叫做控制进程。
结合Linux命令ps来查看一下上述几个概念的恩怨情仇,我们看下我们常用的 ps -o pid,ppid,pgid,sid,comm | less 执行结果:
第一行分别是PID,PPID,PGID,SID,COMMAND,依次分别是进程ID,该进程父进程ID,进程组ID,会话ID,命令。
通过最后一列,我们知道第二行就是bash也就是bash shell进程,其进程ID为15793,其父进程为13291,进程组ID为15793,会话ID也会15793,结合前面的概念,我们可以知道bash shell就是该进程组组长。
第三行则是ps命令的进程,其进程ID为15816,他是由于bash进程fork出来的,所以他的父进程ID为15793,然后是他所属的组ID为15816,所属的会话ID依然是15793。
最后一行是less命令的进程,其进程ID为15817,他也是由bash进程fork出来的,所以他的父进程ID也为15793,然后是他所属的组ID为15816,所属的会话ID依然是15793。
简单总结一下:
- 上述三个进程一共形成了两个进程组,bash自己为一组,组ID为15793,组长进程为bash自己 ; ps和less为一组,组ID为15816,组长进程为ps进程
- 上述三个进程属于同一个会话,会话ID为15793,会话首进程为bash进程(待定)